package org.example.utils;

import cn.hutool.http.HttpStatus;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.example.model.*;
import org.openqa.selenium.WebDriver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class CommonUtils {
    private static Logger logger = LoggerFactory.getLogger(CommonUtils.class);

    public static void createTapPage(WebDriver webDriver) {
        webDriver.switchTo().window(webDriver.getWindowHandles().stream().skip(1).findFirst().get());
    }

    /**
     * 滑动查找并点击
     * @param webDriver
     * @param device
     * @param searchArray
     * @param saveFilePath
     * @param isShowClickText
     * @param sleepMillis
     * @param callBack
     * @param callBackParams
     */
    public static void searchOcrWidgetWithSwipeAndClick(WebDriver webDriver, Device device, String [] searchArray, String saveFilePath, boolean isShowClickText, Long sleepMillis, CallBack callBack, Object ... callBackParams) {
        Widget widget = findMoreWidgetByOcrWithSwipe(webDriver, device, searchArray, saveFilePath);
        if (widget != null) {
            if (isShowClickText) {
                GlobalUtils.logi(widget.getText());
            }
            myClick(webDriver, device, widget, 2000L);
            if (sleepMillis != null && sleepMillis > 0) {
                GlobalUtils.sleep(sleepMillis);
            }

            if (callBack != null) {
                callBack.execute(callBackParams);
            }
        }
    }

    public static void searchOcrWidgetAndClick(WebDriver webDriver, Device device, String [] searchArray, String saveFilePath, boolean isShowClickText, Long sleepMillis, CallBack callBack, Object ... callBackParams) {
        Widget widget = findMoreWidgetByOcr(webDriver, searchArray, saveFilePath);
        if (widget != null) {
            if (isShowClickText) {
                GlobalUtils.logi(widget.getText());
            }
            myClick(webDriver, device, widget, 2000L);
            if (sleepMillis != null && sleepMillis > 0) {
                GlobalUtils.sleep(sleepMillis);
            }

            if (callBack != null) {
                callBack.execute(callBackParams);
            }
        }
    }

    /**
     * 通过ocr查找组件
     * @param webDriver
     * @param searchArray
     * @param saveFilePath
     * @return
     */
    public static Widget findMoreWidgetByOcrWithSwipe(WebDriver webDriver, Device device, String [] searchArray, String saveFilePath) {
        for (int i = 0; i < 5; i++) {
            swipeDown(webDriver, device);
            GlobalUtils.sleep(1000);
            Widget widget = findMoreWidgetByOcr(webDriver, searchArray, saveFilePath, false);
            if (widget != null) {
                return widget;
            }
        }

        for (int i = 0; i < 5; i++) {
            swipeUp(webDriver, device);
            GlobalUtils.sleep(1000);
            Widget widget = findMoreWidgetByOcr(webDriver, searchArray, saveFilePath, false);
            if (widget != null) {
                return widget;
            }
        }
        return null;
    }

    /**
     * 通过ocr查找组件
     * @param webDriver
     * @param searchArray
     * @param saveFilePath
     * @return
     */
    public static Widget findMoreWidgetByOcr(WebDriver webDriver, String [] searchArray, String saveFilePath) {
        return findMoreWidgetByOcr(webDriver, searchArray, saveFilePath, false);
    }

    /**
     * 通过ocr查找组件
     * @param webDriver
     * @param searchArray
     * @param saveFilePath
     * @param isShowLog 是否显示日志
     * @return
     */
    public static Widget findMoreWidgetByOcr(WebDriver webDriver, String [] searchArray, String saveFilePath, boolean isShowLog) {
        if (searchArray == null || searchArray.length <= 0) {
            return null;
        }
        List<Widget> widgetList = OcrUtils.ocrImg(webDriver, saveFilePath);
        if (widgetList.size() == 0) {
            if (isShowLog) {
                GlobalUtils.logi("识别结果为空！");
            }
            return null;
        }
        if (isShowLog) {
            GlobalUtils.logi(JSON.toJSONString(widgetList));
        }
        Widget targetWidget = null;
        for (Widget widget : widgetList) {
            String widgetText = widget.getText();
            for (int i = 0; i < searchArray.length; i++) {
                Pattern pattern = Pattern.compile(searchArray[i]);
                Matcher matcher = pattern.matcher(widgetText);
                if (matcher.matches()) {
                    targetWidget = widget;
                    break;
                }
            }
        }
        if (isShowLog) {
            if (targetWidget != null) {
                GlobalUtils.logi(JSON.toJSONString(targetWidget));
            } else {
                GlobalUtils.logi("未匹配到：" + JSON.toJSONString(searchArray));
            }
        }

        return targetWidget;
    }

    public static List<Tess4JWidget> convertOcrToWidget(String ocrContent) {
        if (StringUtils.isEmpty(ocrContent)) {
            return null;
        }
        JSONObject jsonObject = JSON.parseObject(ocrContent);
        Integer code = jsonObject.getInteger("code");
        if (code == HttpStatus.HTTP_OK) {
            JSONObject data = jsonObject.getJSONObject("data");
            JSONArray rawOutArray = data.getJSONArray("raw_out");
        }
        return null;
    }

    /**
     * 清理后台
     * @param webDriver
     * @param device
     */
    public static void clearBackApps(WebDriver webDriver, Device device) {
        GlobalUtils.sleep(1000);
        GlobalUtils.home(webDriver);
        GlobalUtils.sleep(1000);
        double y1 = device.getHeight() * 0.04;//每一次点击都增加3%
        double y2 = device.getHeight() * 0.2;  // 要点击的范围
        Double yy = device.getHeight() - y1;
        double sum = 0;
        GlobalUtils.logi("开启清理后台软件，请给不清理的软件上锁");
        while (true) {
            sum += y1;
            if (sum <= y2) {
                GlobalUtils.recents(webDriver);
                GlobalUtils.sleep(5000);
                String [] array = {"清除", "清除全部", "全部关闭"};
                Widget clearBtn = CommonUtils.findMoreWidgetByOcr(webDriver, array, null);
                if (clearBtn != null) {
                    // 这里不要扩大范围点击
                    CommonUtils.myClick(webDriver, device, clearBtn);
                    GlobalUtils.sleep(1000);
                    break;
                } else {
                    int xx = device.getWidth() / 2;
                    GlobalUtils.click(webDriver, device, xx, yy.intValue());
                }

                GlobalUtils.sleep(2000);

                GlobalUtils.home(webDriver);
                yy -= y1;
                GlobalUtils.sleep(3000);

            } else {
                break;
            }


        }
        GlobalUtils.home(webDriver);
        GlobalUtils.sleep(2000);
    }


    /**
     * 随机睡眠
     * @param milSeconds
     * @return
     */
    public static long randomSleep(long milSeconds) {
        long sleepTime = randomLong(milSeconds - 500, milSeconds + 500);
        GlobalUtils.sleep(sleepTime);
        return sleepTime;
    }

    /**
     * 随机睡眠
     * @param minMilSeconds
     * @param maxMilSeconds
     * @return
     */
    public static long randomSleep(long minMilSeconds, long maxMilSeconds) {
        long sleepTime = randomLong(minMilSeconds, maxMilSeconds);
        GlobalUtils.sleep(sleepTime);
        return sleepTime / 1000;
    }

    /**
     *
     * @param webDriver
     * @param device
     * @param widget
     * @param delayMillisecond 延迟指定毫秒后再点击
     */
    public static void myClick(WebDriver webDriver, Device device, Widget widget, Long delayMillisecond) {
        if (delayMillisecond != null || delayMillisecond > 0) {
            GlobalUtils.sleep(delayMillisecond);
        }
        myClick(webDriver, device, widget);
    }

    public static void myClick(WebDriver webDriver, Device device, Widget widget) {
        if (widget == null) {
            System.out.println("widget 无效！");
        }
        // x + width / 2
        int centerX = widget.getX().intValue() + (widget.getWidth().intValue() / 2);
        // y + height / 2
        int centerY = widget.getY().intValue() + (widget.getHeight().intValue() / 2);
        // logi('获取到点击位置：center_x == ' + center_x + ',center_y == ' + center_y)
        System.out.println("获取到点击位置：centerX == " + centerX + ",centerY == " + centerY);
        logger.info("获取到点击位置：centerX == " + centerX + ",centerY == " + centerY);
        GlobalUtils.click(webDriver, device, centerX, centerY);
    }

    /**
     * 上滑
     * @param webDriver
     * @param device
     */
    public static void swipeUp(WebDriver webDriver, Device device) {
        int widthStart = randomInt(device.getWidth() / 2 - 50, device.getWidth() / 2 + 50);
        int heightStart = randomInt(device.getHeight() / 10 * 8 - 100, device.getHeight() / 10 * 8 + 100);
        int widthEnd = randomInt(device.getWidth() / 2 - 50, device.getWidth() / 2 + 50);
        int heightEnd = randomInt(device.getHeight() / 10 * 2 - 100, device.getHeight() / 10 * 2 + 100);
        int randomSwipeDuration = randomInt(300, 500);
        GlobalUtils.swipe(webDriver, device, widthStart, heightStart, widthEnd, heightEnd, randomSwipeDuration);
    }

    /**
     * 下拉
     * @param webDriver
     * @param device
     */
    public static void swipeDown(WebDriver webDriver, Device device) {
        int widthStart = randomInt(device.getWidth() / 4 * 3 - 100, device.getWidth() / 4 * 3 + 100);
        int heightStart = randomInt(device.getHeight() / 4 - 50, device.getHeight() / 4 + 50);
        int widthEnd = randomInt(device.getWidth() / 4 * 3 - 100, device.getWidth() / 4 * 3 + 100);
        int heightEnd = randomInt(device.getHeight() / 4 * 3 - 50, device.getHeight() / 4 * 3 + 50);
        int randomSwipeDuration = randomInt(300, 500);
        GlobalUtils.swipe(webDriver, device, widthStart, heightStart, widthEnd, heightEnd, randomSwipeDuration);
    }

    /**
     * 左滑
     * @param webDriver
     * @param device
     */
    public static void swipeLeft(WebDriver webDriver, Device device) {
        int widthStart = randomInt(device.getWidth() / 3 * 2 - 100, device.getWidth() / 3 * 2 + 100);
        int heightStart = randomInt(device.getHeight() / 4 * 3 - 50, device.getHeight() / 4 * 3 + 50);
        int widthEnd = randomInt(50 - 20, 50 + 20);
        int heightEnd = randomInt(device.getHeight() / 4 * 3 - 50, device.getHeight() / 4 * 3 + 50);
        int randomSwipeDuration = randomInt(300, 500);
        GlobalUtils.swipe(webDriver, device, widthStart, heightStart, widthEnd, heightEnd, randomSwipeDuration);
    }

    /**
     * 右滑
     * @param webDriver
     * @param device
     */
    public static void swipeRight(WebDriver webDriver, Device device) {
        int widthStart = randomInt(50 - 20, 50 + 20);
        int heightStart = randomInt(device.getHeight() / 4 * 3 - 50, device.getHeight() / 4 * 3 + 50);
        int widthEnd = randomInt(device.getWidth() / 3 * 2 - 100, device.getWidth() / 3 * 2 + 100);
        int heightEnd = randomInt(device.getHeight() / 4 * 3 - 50, device.getHeight() / 4 * 3 + 50);
        int randomSwipeDuration = randomInt(300, 500);
        GlobalUtils.swipe(webDriver, device, widthStart, heightStart, widthEnd, heightEnd, randomSwipeDuration);
    }

    public static int randomInt(int min, int max) {
        Random random = new Random();
        return random.nextInt((max - min) + 1) + min;
    }

    public static long randomLong(long min, long max) {
        int minInt = Integer.parseInt(min + "");
        int maxInt = Integer.parseInt(max + "");
        return randomInt(minInt, maxInt);
    }
}
